/*** Class Name: iFulfillBatchJob
 * Author: Accenture
 * Date: 19-July-2011
 * Requirement/Project Name: iFulfill
 * Requirement Description: Daily Job to check if all the FI associated with a Pending Inactivation WF are Completed. Marks the WF is Inactive if all FI are completed.
 **/

global class iFulfillBatchJob implements Database.Batchable<sObject>
{
    private final String  query;    
    /** Constructor **/
    global iFulfillBatchJob ()
    {
      // Get the Workflow which is in Pending inactive state.      
      query = 'select status__c,ID from Workflow_Definition__c where Status__c = \''+ IfullfillTextConstant.WF_DEF_PENDING_IN_ACTIVATION_STATUS +'\'';
    }
     //The executeBatch method is called for each chunk of records returned from start.   
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
          return Database.getQueryLocator(query);
    }
    
    global  void execute(Database.BatchableContext BC, List<sObject> scope)
    {
          // Store Id and Workflowdef in Map    
        Map<ID, Workflow_Definition__c> wfDefMap= new Map<ID, Workflow_Definition__c>();
       
        List<Workflow_Definition__c> updateWfDefList = new List<Workflow_Definition__c>();
        Set<ID> workflowDefID = new Set<ID>();   
        Set<ID> assignedWorkflowIds = new Set<ID>();   
        Workflow_Definition__c wfDefObj =null;
      
        for(sObject sObj : scope)
        {
            wfDefObj= ((Workflow_Definition__c)sObj );
            workflowDefId.add(wfDefObj.id);
            wfDefMap.put(wfDefObj.id ,wfDefObj );
        }
        
        wfDefObj =null;        
        // Get the FI (which are not complete) object associated with the workflow.        
        List<Fullfilment_Item__c> fullFilmentItemList = ([select Workflow_Code__c   , name,id, status__c from Fullfilment_Item__c where Workflow_Code__c in :workflowDefID and (Status__c!= :IfullfillTextConstant.FI_WORKFLOW_CANCELED_STATUS  and Status__c!= :IfullfillTextConstant.FI_WORKFLOW_LIVE_STATUS  and Status__c!= :IfullfillTextConstant.FI_WORKFLOW_OUTED_STATUS)]);    
                                                             
        for(Fullfilment_Item__c fiObj :fullFilmentItemList)
        {
             assignedWorkflowIds.add(fiObj.Workflow_Code__c); 
        }
        
        // remove all the workflow id if non-complete FI is associated with it
        workflowDefId.removeAll(assignedWorkflowIds);
        System.debug('Pending inactive workflow'+ workflowDefId);       
        if(workflowDefId.size()>0)
        {
            for(id wfID :workflowDefId )
            {
                wfDefObj = wfDefMap.get(wfID );
                wfDefObj.status__c = IfullfillTextConstant.WF_DEF_INACTIVE_STATUS;
                updateWfDefList.add(wfDefObj);
            }
        }
        try
        {
              // update worklow
            if(updateWfDefList.size()>0)
            {
                update updateWfDefList ;
            }
         } 
         catch(DMLException ex)
         {
             GeneralConstants.mailAnyExceptionToMe('iFulfillBatchJob ','execute',ex);
             System.debug('Error while updating the FI object');
         }
         catch(Exception e)
         {
             GeneralConstants.mailAnyExceptionToMe('iFulfillBatchJob ','execute',e);
             System.debug('Error while updating the FI object');
         }
    }
    /*
    * The finish method is called after all batches are processed. Use this method to send confirmation emails or execute
    * post-processing operations.
    *
    **/
    global void finish(Database.BatchableContext BC)
    {
    } 
}